home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / backup / dds2tar-.000 / dds2tar-2.4.12.tar / dds2tar-2.4.12 / zf-cre-open.c < prev    next >
C/C++ Source or Header  |  1996-01-28  |  4KB  |  222 lines

  1.  
  2. /*
  3.  * This file is part of dds2tar.
  4.  * Copyright by J"org Weule
  5.  *
  6.  * Copyright: GPL
  7.  */
  8.  
  9. /*
  10.  * If you compile this file with -DTEST, you will get a test program:
  11.  *
  12.  *     cc dds_fio.c -DTEST -o dds_fio && dds_fio
  13.  *
  14.  * The test shows the use of ccopen(...) to pipe stdout through /bin/grep.
  15.  *
  16.  * The interface should be useful in many cases.
  17.  */
  18.  
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <sys/mtio.h>
  22. #include <string.h>
  23. #include <unistd.h>        /* pipe() ... */
  24. #include <sys/types.h>        /* size_t, open() */
  25. #include <sys/wait.h>        /* wait() */
  26. #include <sys/stat.h>        /* open() */
  27. #include <fcntl.h>        /* open() */
  28.  
  29. #include "zf-cre-open.h"
  30.  
  31. #define streq(a,b) (!strcmp((a),(b)))
  32.  
  33. FILE   *
  34. zfopen(
  35.           char const *const name,
  36.           int const compressed,
  37.           char const *const open_mode
  38. )
  39. {
  40.  
  41.     FILE   *fp;
  42.     char   *b;
  43.  
  44.     b = malloc(1024);
  45.     if (b == NULL)
  46.         exit(20);
  47.  
  48.     if (compressed == T_MODE) {
  49.         if ((name != NULL) && (strcmp(name, "-"))) {
  50.             fp = fopen(name, open_mode);
  51.             if (fp == NULL) {
  52.                 perror("dds2tar");
  53.                 exit(21);
  54.             }
  55.         } else if (streq(open_mode, "w")) {
  56.             fp = stdout;
  57.         } else {
  58.             fp = stdin;
  59.         }
  60.         return fp;
  61.     }
  62.     if (streq(open_mode, "w")) {
  63.         strcpy(b, "gzip ");
  64.         if ((name != NULL) && (strcmp(name, "-"))) {
  65.             strcat(b, " > ");
  66.             strcat(b, name);
  67.         }
  68.     } else if (streq(open_mode, "r")) {
  69.         strcpy(b, "gunzip --force --decompress --stdout ");
  70.         if ((name != NULL) && (strcmp(name, "-"))) {
  71.             strcat(b, name);
  72.         }
  73.     }
  74.     fp = popen(b, open_mode);
  75.     if (fp == NULL) {
  76.         perror("dds2tar");
  77.         exit(22);
  78.     }
  79.     free(b);
  80.     return fp;
  81. }
  82.  
  83.  
  84. int
  85. cclose(int const fd)
  86. {
  87.     int     status = 0;
  88.  
  89.     close(fd);
  90.     wait(&status);
  91.     return status;
  92. }
  93.  
  94. int
  95. reopen(
  96.           int const stdfd,
  97.           char const *const output_file,
  98.           int const mode,
  99.           int const flags
  100. )
  101. {
  102.     int     fd;
  103.  
  104.     if (!strcmp(output_file, "-")) {
  105.         /* use stdout */
  106.         fd = 1;
  107.     } else {
  108.         /* open file */
  109.         if ((fd = open(output_file, mode, flags)) == -1) {
  110.             perror("dds2tar");
  111.             exit(23);
  112.         }
  113.         /* don't know why this happens. Any idea? */
  114.         if (fd == 0) {    /* normally 0 is stdin!! */
  115.             perror("dds2tar");
  116.             exit(24);
  117.         }
  118.     }
  119.     if (0 <= stdfd) {
  120.         dup2(fd, stdfd);
  121.         close(fd);
  122.         fd = stdfd;
  123.     }
  124.     return fd;
  125. }
  126.  
  127. /*
  128.  * creopen opens a pipe to a child process with the file number 'stdfd'
  129.  * on file number 'stdfd_child' of the child.
  130.  * The files are close as needed (see dup2(2)).
  131.  */
  132.  
  133. int
  134. creopen(
  135.            int const stdfd_parent,    /* stdfd should not be == 3 */
  136.            int const stdfd_child,    /* stdfd_child must be 1 or 2 */
  137.            char const *const filename,
  138.            char const *const *argv
  139. )
  140. {
  141.     int     fd;
  142.     int     pid;
  143.     int     pipefd[2];
  144.     int     pipe_parent;
  145.  
  146.     if ((stdfd_child & 0xfffffffe) != 0 || stdfd_child == stdfd_parent) {
  147.         fprintf(stderr, "creopen not useful with that parameters\n");
  148.         exit(25);
  149.     }
  150.     pipe_parent = stdfd_child ^ 1;
  151.     if (pipe(pipefd) < 0) {    /* create pipe with two fd's */
  152.         perror("dds2tar");
  153.         exit(26);
  154.     }
  155.     if ((pid = fork()) == 0) {    /* we are the child process */
  156.         /* reconnect pipe to child */
  157.         dup2(pipefd[stdfd_child], stdfd_child);
  158.         close(pipefd[0]);    /* close input of pipe */
  159.         close(pipefd[1]);    /* close output of pipe */
  160.         /* the prototype of execv is wrong */
  161.         execv(filename, (char *const *) argv);
  162.         perror("dds2tar");
  163.         exit(27);
  164.     }
  165.     if (pid <= 0) {
  166.         perror("dds2tar");
  167.         exit(28);
  168.     }
  169.     /*
  170.      * We are the parent process.
  171.      */
  172.     close(stdfd_child);
  173.     fd = pipefd[pipe_parent];
  174.     if ((0 <= stdfd_parent) && (stdfd_parent <= 1)) {
  175.         dup2(fd, stdfd_parent);
  176.         close(fd);
  177.         fd = stdfd_parent;
  178.         close(pipefd[0]);
  179.         close(pipefd[1]);
  180.     }
  181.     return fd;
  182. }
  183.  
  184. #ifdef TEST
  185.  
  186. static char *a[] =
  187. {"grep", "allo", NULL};
  188.  
  189. main(int argc, char **argv, char **envp)
  190. {
  191.  
  192.     int     status;
  193.     int     pid;
  194.     int     fd;
  195.  
  196.     if (!strcmp(argv[1], "-p")) {
  197.     } else {
  198.         if (!strcmp(argv[1], "-o"))
  199.             reopen(1, argv[2], O_RDONLY, 0);
  200.         else
  201.             creopen(1, 0, "/usr/bin/grep", a);
  202.         write(1, "Hallo World -1- \n", 17);
  203.         write(1, "Hi    World -2- \n", 17);
  204.         write(1, "Hallo World -3- \n", 17);
  205.         write(1, "Morgen Welt -4- \n", 17);
  206.         write(1, "Hallo World -5- \n", 17);
  207.         printf("Hallo World =1= \n");
  208.         printf("Hi    World =2= \n");
  209.         printf("Hallo World =3= \n");
  210.         printf("Morgen Welt =4= \n");
  211.         printf("Hallo World =5= \n");
  212.         fflush(stdout);
  213.         if (!strcmp(argv[1], "-o")) {
  214.             close(1);
  215.         } else {
  216.             cclose(1);
  217.         }
  218.     }
  219. }
  220.  
  221. #endif
  222.